﻿/**** begin formWatcher ******/
/* 
// NOTE: the trickiest thing about formWatcher is the way it can handle custom success or before submit functions.  Here is an example:

var formWatcher = new jQuery.v.formWatcher();
formWatcher.registerSuccessFunction('form.someForm', function (data) {
    // do whatever you want here, and when <form class="async someForm" ... > is being posted, this will execute
});

*/

jQuery.v.formWatcher = function (options) {

    this.settings = jQuery.extend({
        watchOnlyFor: 'form.watched',
        asyncSelector: 'form.async',
        validateSelector: 'form.validate',
        confirmSelector: 'form.confirm',
        customBeforeSubmitFunctions: new Array(),
        customSuccessFunctions: new Array(),
        customErrorFunctions: new Array(),
        errorSelector: '#error',
        loadingSelector: '#loading'
    }, options);

    this.init();
};
jQuery.v.formWatcher.instance = null;
jQuery.v.formWatcher.prototype.settings = null;
jQuery.v.formWatcher.prototype.registerBeforeSubmitFunction = function (formSelector, theFunction) {
    this.settings.customBeforeSubmitFunctions[formSelector] = theFunction;
};
jQuery.v.formWatcher.prototype.registerSuccessFunction = function (formSelector, theFunction) {
    this.settings.customSuccessFunctions[formSelector] = theFunction;
};
jQuery.v.formWatcher.prototype.registerErrorFunction = function (formSelector, theFunction) {
    this.settings.customErrorFunctions[formSelector] = theFunction;
};
jQuery.v.formWatcher.prototype.handleSuccessByConvention = function (response, doThisIfNormalSuccess) {
    if (response.IsError) {
        $(this.settings.errorSelector).text(response.Message).show();
    } else if (response.IsRedirect) {
        location.href = response.Message.Url;
    } else {
        doThisIfNormalSuccess(response);
    }
};
jQuery.v.formWatcher.prototype.handleForm = function (event) {
    var settings = event.data.self.settings;
    // in IE6 jQuery(event.target) is the button!!! so, we have to use jQuery(this) to find the form:
    var form = jQuery(this);

    if (form.is(settings.confirmSelector)
        && !confirm('Are you sure you want to ' + form.attr('title') + '?')) {
        event.preventDefault();
        return;
    }

    // search for any custom functions to execute before submit and execute them here
    if (settings.customBeforeSubmitFunctions) {
        for (var key in settings.customBeforeSubmitFunctions) {
            if (form.is(key)) {
                // execute the function we found
                if (!(settings.customBeforeSubmitFunctions[key](form))) {
                    event.preventDefault();
                    return;
                }
                break;
            }
        }
    }

    // asynchronously submit if form is requesting it
    if (form.is(settings.asyncSelector)) {
        event.preventDefault();

        // default to the main success/error handlers
        var relevantSuccess = function () { };
        var relevantError = function () { $(settings.errorSelector, form).text('An unexpected problem occurred.').show(); };

        // optionally, go through the customSuccess functions and see if the form matches any of the selectors
        if (settings.customSuccessFunctions) {
            for (var key in settings.customSuccessFunctions) {
                if (form.is(key)) {
                    // the first match takes precendence, set the relevantSuccess field and go on
                    relevantSuccess = settings.customSuccessFunctions[key];
                    break;
                }
            }
        }
        if (settings.customErrorFunctions) {
            for (var key in settings.customErrorFunctions) {
                if (form.is(key)) {
                    // the first match takes precendence, set the relevantError field and go on
                    relevantError = settings.customErrorFunctions[key];
                    break;
                }
            }
        }

        $(settings.errorSelector, form).hide();
        $(settings.loadingSelector, form).show();
        jQuery.ajax({
            url: form.attr('action'),
            type: form.attr('method'),
            data: form.serialize(),
            success: function(response){
                event.data.self.handleSuccessByConvention(response, relevantSuccess);
            },
            global: false,
            error: relevantError,
            complete: function () {
                $(settings.loadingSelector, form).hide();
            }
        });
    }
};

jQuery.v.formWatcher.prototype.init = function () {
    var self = this;

    jQuery(this.settings.watchOnlyFor).live('submit', { self: this }, this.handleForm);

    // set up the global instance reference to point to this
    jQuery.v.formWatcher.instance = this;

    $(document).bind('newHtml', function (event, parent) {
        parent.find(self.settings.validateSelector).each(function () {
            $.validator.unobtrusive.parse($(this));
        });
    });
};
/**** end formWatcher ******/
